API proposal for NavigateTo and NavLink with relative path#64670
API proposal for NavigateTo and NavLink with relative path#64670ilonatommy merged 17 commits intodotnet:mainfrom
NavigateTo and NavLink with relative path#64670Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a PathRelative navigation option to Blazor's NavigationManager, enabling developers to navigate to URIs relative to the current page's directory path rather than the application's base URI. This addresses a common pain point where navigating to sibling pages required manual path resolution.
Key Changes:
- Adds
NavigationOptions.PathRelativeproperty for path-relative navigation - Implements
ResolveRelativeToCurrentPathmethod using zero-allocation span-based operations - Adds TypeScript interface definition for JavaScript interop
- Includes 7 unit tests covering basic scenarios and edge cases
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Components/Components/src/NavigationOptions.cs | Adds PathRelative boolean property to NavigationOptions struct with XML documentation |
| src/Components/Components/src/NavigationManager.cs | Implements path-relative resolution logic in NavigateTo and new internal ResolveRelativeToCurrentPath method |
| src/Components/Components/src/PublicAPI.Unshipped.txt | Registers the new public API property and its init accessor |
| src/Components/Components/test/NavigationManagerTest.cs | Adds unit tests for path-relative navigation scenarios and helper class for tracking navigations |
| src/Components/Web.JS/src/Services/NavigationManager.ts | Adds optional pathRelative field to TypeScript NavigationOptions interface |
|
I don't think we should take this change.
This is not a thing in the web. The original issue refers to users hosting inside MVC and not adding a This change doesn't address that and introduces a way of composing a path that doesn't make sense. There is a way of creating relative URLs which is using Absolute URL means a complete URI with scheme and authority (for example
When a browser sees a non‑absolute string it runs the URL resolution algorithm: if a Relationship of
|
|
Let's discuss it a bit more.
I was inspired by this API: https://angular.dev/guide/routing/navigate-to-routes#routernavigate. Blazor would not be a pioneer in allowing
I don't believe so, the original issue is about blazor treating nested paths not as dirs but like a route, so not recognizing that in What do you think? |
NavigateTo with relative pathNavigateTo and NavLink with relative path
For the future reviewers: this conversation is resolved. We agreed the feature is really missing. |
pavelsavara
left a comment
There was a problem hiding this comment.
I would like to also use NavigationManager.NavigateTo("./configuration.html"); and NavigationManager.NavigateTo("../../configuration.html"); to express relative path, instead of passing the option.
That's a justified ask but |
I'm naive user of this API. I would not know/notice that it could sometimes refer to baseURI and sometimes to absolute root. I would have hard time to discover the optional option parameter. Does What would |
Let's do it by an example. We have an application with
Is it still confusing? |
|
@pavelsavara what this API does is offer a convenience method to generate document relative urls independent of the existence of a Without a
|
| Link | Without <base> |
With <base href="/base/"> |
|---|---|---|
/products/ |
/products |
/products |
Edit/ |
/base/Customer/5/Edit/ |
/base/Edit/ |
./Edit/ |
/base/Customer/5/Edit/ |
/base/Edit/ |
../Details/ |
/base/Customer/5/Details/ |
/Details/ |
../../Orders/ |
/base/Orders/ |
/Orders/ |
ASP.NET Core MVC's URL generation APIs (Url.Action(), Url.RouteUrl(), LinkGenerator, <a asp-action="">) always produce absolute URLs (starting with /), which are unaffected by the <base> tag. This pattern is used heavily across MVC apps in views, controllers, and middleware.
The option switches resolution from base-relative to document-relative, resolving as if there were no <base> tag.
Current URL: https://example.com/base/Customer/5/Details with <base href="/base/"> so "../Details/", new NavigationOptions { PathRelative = true } becomes base/Customer/5/Details/ instead of /Details/.
The goal is to explicitly enable document-relative resolution when needed, without breaking existing code.
How does the migration process look like ? With this API they would have to add |
Because currently they are using absolute paths, there's no magic way to migrate. Users would have to rename each place with |
No. The right level to do this is to provide an option on the API in navigation manager. Most people don't use or need this. It's a convenience API for the few people that have requested it. They can already achieve this themselves. Anything bigger than offering an option on the existing navigation manager API and maybe something in NavLink is out of the scope and will require a proper design document and justification for the work. Let's not turn a simple enhancement into a redesign of an area. |
Summary
This change implements the
RelativeToCurrentUriparameter for Blazor'sNavigationManager.NavigateTo()andNavLinkcomponent, allowing developers to navigate to URIs relative to the current page path rather than the application's base URI.Background
You have a Blazor app with nested folder structure like a file explorer or documentation site:
When you're at
/docs/getting-started/installation.htmland want to navigate to a sibling page:the navigation redirects to
/configuration.html(app root), instead of the expected/docs/getting-started/configuration.htmlThe same limitation affected
NavLinkcomponents.Fixes #23615
Changes
Public API
Implementation Details
NavigationManager: When
RelativeToCurrentUriistrue,NavigateTo()callsResolveRelativeToCurrentPath()to compute the absolute URI using zero-allocation span-based operations before passing it toNavigateToCore().NavLink: When
RelativeToCurrentUriistrue,OnParametersSet()resolves the relative href server-side during rendering, ensuring the anchor tag contains the correct absolute path for SSR scenarios.Performance: The implementation avoids creating
Uriobjects, using onlyReadOnlySpan<char>operations andstring.Concat()for efficiency.Tests
Added 7 NavigationManager tests and 6 NavLink tests covering path-relative navigation, query/fragment handling, nested paths, and edge cases.
Usage
NavigationManager:
NavLink: